home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-05 / netbtime.zip / TIMERECV.ASM < prev    next >
Assembly Source File  |  1993-03-09  |  44KB  |  936 lines

  1.                 TITLE   TIMERECV
  2.                 PAGE    65,132
  3. ;╔═══════════════════════════════════════════════════════════════════════════╗
  4. ;║      TIMERECV -- A TSR to Receive Periodically Broadcasted Time           ║
  5. ;║                                                                           ║
  6. ;║     I am the original author of this work and hereby place it into        ║
  7. ;║     the public domain.  If your conscience bothers you, please feel       ║
  8. ;║     free to send me $25.00 so that I may provide more such goodies.       ║
  9. ;║                                                                           ║
  10. ;║     NOTE:  This source code was written to be assembled with OPTASM.      ║
  11. ;║            Phase errors and near jump problems will surely occur if       ║
  12. ;║            MASM is used.  Also, this program must be constructed as       ║
  13. ;║            a .COM file.                                                   ║
  14. ;║                                                                           ║
  15. ;║     Programmer ...... George W. Mays                                      ║
  16. ;║     Date ............ February, 1993                                      ║
  17. ;║     Site ............ 3314 Prince George                                  ║
  18. ;║                       San Antonio, TX 78230                               ║
  19. ;║     Source .......... 80286 Assembler                                     ║
  20. ;║     System .......... IBM PC/AT Compatible System Under MSDOS             ║
  21. ;║                                                                           ║
  22. ;╚═══════════════════════════════════════════════════════════════════════════╝
  23.                 .286
  24. CSEG    SEGMENT PARA    PUBLIC  'CODE'
  25.  
  26.         ASSUME  CS:CSEG,DS:NOTHING,ES:NOTHING,SS:NOTHING
  27.  
  28.                 INCLUDE NETBIOS.INC 
  29.  
  30.                 ORG     100H                    ;SKIP TO END OF THE PSP
  31. ENTPT:          JMP     INITIALIZE              ;COM FILE ENTRY ALWAYS AT 100H
  32.  
  33. COPYRIGHT       DB      "TIMERECV V1.0, (C) 1993, G.W. Mays",0Ah,0Dh
  34.                 DB      "In the Public Domain.  Use Freely.",0Ah,0Dh,'$'
  35.  
  36. ;╒═══════════════════════════════════════════════════════════════════════════╕
  37. ;│ Program data area.  Buffers & Stack at end of resident code.              │
  38. ;╘═══════════════════════════════════════════════════════════════════════════╛
  39. ;
  40. ;       Data Stuff
  41. STACKSIZE       EQU     0200h                   ;Our stack size
  42. VER             DW      0                       ;DOS version as returned
  43. DOSMAJOR        DB      0                       ;DOS major version number
  44. DOSMINOR        DB      0                       ;DOS minor version number
  45. REDIRACTIVE     DB      0                       ;Redirector flag
  46. HAVEBUFF        DB      0                       ;Flag, data has been received
  47. LASTSTATUS      DB      0                       ;Completion code from last recv
  48. NAMENUM         DB      0                       ;Name Number returned by NB
  49. TEN             DB      10                      ;Handy constant 10 decimal
  50. ZERO            DB      0                       ;Handy constant 0
  51. HUNDRED         DW      100                     ;Handy constant 100 decimal
  52. SEMAPHORE       DW      0FFFFh                  ;Serialize interrupt processing
  53. SAVE_SP         DW      0                       ;Stack save cells
  54. SAVE_SS         DW      0
  55. BUFF            DB      "                "      ;Data buff for NB receive
  56. DATETIME        DB      "                "      ;Copy of above data buffer
  57. PREV1Ch         DD      0                       ;Addr of original 1C Handler
  58. PREV28h         DD      0                       ;Addr of original 28 Handler
  59. INDOS           DD      0                       ;Addr of INDOS flag
  60. CRIT            DD      0                       ;Addr of critical error flag
  61. COUNTER         DW      0                       ;Tick counter
  62. NTICKS          DW      182                     ;Tick count to trip action
  63. MYNAME          DB      "TIMECLIENT      "      ;My NETBIOS name
  64. HISNAME         DB      "TIMESERVER      "      ;Sender NETBIOS name
  65. CB              NCB     <>                      ;Our NCB             
  66.  
  67.  
  68. ;╒═══════════════════════════════════════════════════════════════════════════╕
  69. ;│ Control is passed here by DOS via INT 0x1C (the Timer interrupt).         │
  70. ;│                                                                           │
  71. ;│ A quick word about stack handling....  We don't want to risk blowing      │
  72. ;│ the stack on the poor guy who gets interrupted.  So we use our own        │
  73. ;│ stack.  However, that presents a problem since the INT 1C handler         │
  74. ;│ could conceivably be interrupted by INT 28 processing (and vice-          │
  75. ;│ versa).  To avoid the conflicts that such a scenario would give rise      │
  76. ;│ to, access to our stack is serialized by use of a semaphore.  In this     │
  77. ;│ way, only the first guy to the semaphore gets control of it and hence     │
  78. ;│ implicitly is the one who may use our stack.  Those failing to get        │
  79. ;│ control of the semaphore simply say "never mind" and skip their           │
  80. ;│ attempts at processing for one service cycle.                             │
  81. ;│                                                                           │
  82. ;╘═══════════════════════════════════════════════════════════════════════════╛
  83.  
  84. INT_1C          PROC    FAR
  85.  NOP ;          INT     3                       ;Debug or NOP
  86.                 PUSHF                           ;Save flags
  87.                 PUSH    DS              
  88.                 PUSH    AX
  89. ; Bump & Test Counter
  90.                 MOV     AX,CS                   ;Set up addressing
  91.                 MOV     DS,AX
  92.                 MOV     AX,COUNTER              ;Bump counter
  93.                 INC     AX
  94.                 MOV     COUNTER,AX      
  95.                 CMP     AX,NTICKS               ;Have we hit "NTICKS"?
  96.                 JB      RESTORE                 ;No, restore & return
  97.  
  98.                 INC     CS:SEMAPHORE            ;Enqueue the stack
  99.                 JNZ     DEQUEUE                 ;Busy?
  100.                                                 ;No, fall thru...
  101. ; Time to Examine Broadcasted Date/Time
  102.                 CLI                             ;Set our stack
  103.                 MOV     CS:SAVE_SP,SP           ;Save stack address
  104.                 MOV     SP,SS                   ;
  105.                 MOV     CS:SAVE_SS,SP
  106.                 MOV     SP,CS                   
  107.                 MOV     SS,SP                   
  108.                 MOV     SP,OFFSET STACKTOP      ;             
  109.                 STI
  110.                 PUSH    ES                      ;Save registers
  111.                 PUSH    DI
  112.                 PUSH    SI
  113.                 PUSH    DX
  114.                 PUSH    CX
  115.                 PUSH    BX
  116. ; The Reason We Came ----------------------------
  117.                 MOV     AL,00h                  ;00h means DOS not busy
  118.                 CALL    DOTIME                  ;Process date/time received
  119. ; -----------------------------------------------
  120.                 POP     BX                      ;Restore registers
  121.                 POP     CX
  122.                 POP     DX
  123.                 POP     SI
  124.                 POP     DI
  125.                 POP     ES
  126.                 CLI
  127.                 MOV     SP,CS:SAVE_SS           ;Restore stack address
  128.                 MOV     SS,SP                   
  129.                 MOV     SP,CS:SAVE_SP
  130.                 STI
  131. DEQUEUE:
  132.                 DEC     CS:SEMAPHORE            ;Dequeue
  133. RESTORE:
  134.                 POP     AX                      ;Restore registers
  135.                 POP     DS
  136.                 POPF                            ;Restore flags and
  137.                 JMP     CS:[PREV1Ch]            ; percolate the call
  138. INT_1C          ENDP
  139.  
  140.  
  141. ;╒═══════════════════════════════════════════════════════════════════════════╕
  142. ;│ Control is passed here by DOS via INT 0x28 (the Idle interrupt).          │
  143. ;│                                                                           │
  144. ;│ This routine is a bit different from the timer interrupt service          │
  145. ;│ routine.  It does NOT bump the COUNTER; it simply tests to see if         │
  146. ;│ COUNTER has already been bumped past NTICKS by the timer interrupt        │
  147. ;│ service routine.  This happens, presumably, when the system is at         │
  148. ;│ the command prompt (i.e. it is "in DOS") and hence we cannot do           │
  149. ;│ our DOS calls from the timer interrupt routine.  The timer ticks          │
  150. ;│ continue to count - we just can't call DOS to set the date/time           │
  151. ;│ so we continue to pop in and out waiting for the INDOS flag to            │
  152. ;│ clear, which it won't when you're waiting at the command prompt.          │
  153. ;│ Alas, DOS generates this interrupt (28h) periodically while it is         │
  154. ;│ servicing buffered keyboard input, which, as fate would have it,          │
  155. ;│ is just what COMMAND.COM is waiting on at the command prompt.             │
  156. ;│                                                                           │
  157. ;╘═══════════════════════════════════════════════════════════════════════════╛
  158.  
  159. INT_28          PROC    FAR
  160.                 PUSHF                           ;Save flags
  161.                 PUSH    DS              
  162.                 PUSH    AX
  163.  
  164.                 INC     CS:SEMAPHORE            ;Enqueue the stack
  165.                 JNZ     SKIPIT                  ; busy...
  166. ; Test Counter
  167.                 MOV     AX,CS                   ;Set up addressing
  168.                 MOV     DS,AX
  169.                 MOV     AX,COUNTER              ;Bump counter
  170.                 CMP     AX,NTICKS               ;Have we hit "NTICKS"?
  171.                 JB      SKIPIT                  ;No, restore & return
  172.                                                 ;Yes, fall thru...
  173. ; Time to Examine Broadcasted Date/Time
  174.                 CLI                             ;Set our stack
  175.                 MOV     CS:SAVE_SP,SP           ;Save stack address
  176.                 MOV     SP,SS                   ;
  177.                 MOV     CS:SAVE_SS,SP
  178.                 MOV     SP,CS                   
  179.                 MOV     SS,SP                   
  180.                 MOV     SP,OFFSET STACKTOP      ;             
  181.                 STI
  182.                 PUSH    ES                      ;Save registers
  183.                 PUSH    DI
  184.                 PUSH    SI
  185.                 PUSH    DX
  186.                 PUSH    CX
  187.                 PUSH    BX
  188. ; The Reason We Came ----------------------------
  189.                 MOV     AL,01h                  ;01h means DOS not busy
  190.                 CALL    DOTIME                  ;Process date/time received
  191. ; -----------------------------------------------
  192.                 POP     BX                      ;Restore registers
  193.                 POP     CX
  194.                 POP     DX
  195.                 POP     SI
  196.                 POP     DI
  197.                 POP     ES
  198.                 CLI
  199.                 MOV     SP,CS:SAVE_SS           ;Restore stack address
  200.                 MOV     SS,SP                   
  201.                 MOV     SP,CS:SAVE_SP
  202.                 STI
  203. SKIPIT: 
  204.                 DEC     CS:SEMAPHORE            ;Dequeue
  205.                 POP     AX                      ;Restore registers
  206.                 POP     DS
  207.                 POPF                            ;Restore flags and
  208.                 JMP     CS:[PREV28h]            ; percolate the call
  209. INT_28          ENDP
  210.  
  211.  
  212. ;╒═══════════════════════════════════════════════════════════════════════════╕
  213. ;│ Get date & time from BIOS; pack 'em up & ship 'em out....                 │
  214. ;╘═══════════════════════════════════════════════════════════════════════════╛
  215.                                                                       
  216. DOTIME          PROC    NEAR 
  217.  NOP ;          INT     3                       ;Debug or NOP
  218.                 CMP     HAVEBUFF,00h            ;Do we have date/time yet?
  219.                 JZ      BEATFEET                ;No, BEATFEET
  220.                 LES     BX,INDOS                ;Did we interrupt DOS?
  221.                 CMP     AL,BYTE PTR ES:[BX]
  222.                 JNE     BEATFEET                ;Yes, BEATFEET
  223.                 LES     BX,CRIT                 ;Critical error handler active?
  224.                 CMP     BYTE PTR ES:[BX],00h             
  225.                 JNZ     BEATFEET                ;Yes, BEATFEET
  226. ; OK - at this point we have received a date/time broadcast, and we know that
  227. ;      we're not stepping on DOS or the Critical Error Handler.
  228.                 CMP     LASTSTATUS,00h          ;If bad last recv status...
  229.                 JNE     NEWRECEIVE              ;Just crank up a new receive
  230.                 CALL    VALIDATE                ;Validate received data
  231.                 JC      NEWRECEIVE              ;Whoa!  Something funky
  232. ;
  233.                 CALL    CONVERTDATE             ;Good D/T frame, set D/T.
  234.                 MOV     AH,2Bh
  235.                 INT     21h
  236.                 CALL    CONVERTTIME
  237.                 MOV     AH,2Dh
  238.                 INT     21h
  239.                 XOR     AX,AX
  240.                 MOV     COUNTER,AX              ;Zero counter
  241. ;
  242. NEWRECEIVE:
  243.                 CALL    CLEARNCB                ;Prepare NCB
  244.                 CALL    BUILDRECEIVE
  245.                 MOV     HAVEBUFF,00h            ;Clear HAVEBUFF flag
  246.                 CALL    CALLNB                  ;Call NETBIOS
  247. BEATFEET:
  248.                 RET                             ;Return
  249. DOTIME          ENDP
  250.  
  251.  
  252. ;╒═══════════════════════════════════════════════════════════════════════════╕
  253. ;│ NBPOST Function --- NETBIOS posts us here upon SEND DATAGRAM completion.  │
  254. ;╘═══════════════════════════════════════════════════════════════════════════╛
  255.  
  256. NBPOST          PROC    NEAR
  257.                 STI                             ;Reenable interrupts
  258.                 PUSH    DS                      ;Save regs
  259.                 PUSH    ES
  260.                 PUSH    AX
  261.                 PUSH    CX
  262.                 PUSH    DI
  263.                 PUSH    SI
  264.                 MOV     AX,CS                   ;Set ES = DS = CS
  265.                 MOV     DS,AX
  266.                 MOV     ES,AX
  267.                 MOV     AL,CB.NCB_RETCODE       ;Tuck away completion status
  268.                 MOV     LASTSTATUS,AL 
  269.                 MOV     AL,CB.NCB_COMMAND
  270.                 MOV     HAVEBUFF,AL             ;Set HAVEBUFF flag  
  271.                 MOV     CX,16                   ;Save data received
  272.                 MOV     DI,OFFSET DATETIME
  273.                 MOV     SI,OFFSET BUFF
  274.                 CLD
  275.                 REP     MOVSB
  276.                 POP     SI
  277.                 POP     DI
  278.                 POP     CX
  279.                 POP     AX                      ;Restore regs
  280.                 POP     ES
  281.                 POP     DS
  282.                 IRET                            ;Return from interrupt
  283. NBPOST          ENDP
  284.  
  285.  
  286. ;╒═══════════════════════════════════════════════════════════════════════════╕
  287. ;│ CLEARNCB Function --- Fill the NCB with binary zeroes.                    │
  288. ;╘═══════════════════════════════════════════════════════════════════════════╛
  289.  
  290. CLEARNCB        PROC    NEAR
  291.                 PUSHF                           ;Save regs & flags
  292.                 PUSH    ES
  293.                 PUSH    DI
  294.                 PUSH    CX
  295.                 PUSH    AX
  296.                 MOV     AX,CS
  297.                 MOV     ES,AX
  298.                 MOV     DI,OFFSET CB            ;Zero the NCB
  299.                 MOV     CX,NCB_SIZE
  300.                 XOR     AL,AL
  301.                 CLD
  302.                 REP     STOSB
  303.                 POP     AX                      ;Restore regs & flags
  304.                 POP     CX
  305.                 POP     DI
  306.                 POP     ES
  307.                 POPF
  308.                 RET
  309. CLEARNCB        ENDP
  310.  
  311.  
  312. ;╒═══════════════════════════════════════════════════════════════════════════╕
  313. ;│ BUILDRECEIVE Function --- Fill in the NCB for a Receive Datagram          │
  314. ;╘═══════════════════════════════════════════════════════════════════════════╛
  315.  
  316. BUILDRECEIVE    PROC    NEAR
  317.                 MOV     AH,NAMENUM              ;Name Number
  318.                 MOV     CB.NCB_NUM,AH
  319.                 MOV     CB.NCB_LENGTH,16        ;Length
  320.                 MOV     AX,CS
  321.                 MOV     ES,AX
  322.                 MOV     CB.NCB_BUFF_SEG,AX      ;Buffer Address and
  323.                 MOV     CB.NCB_POST_SEG,AX      ; Post Address
  324.                 MOV     AX,OFFSET BUFF
  325.                 MOV     CB.NCB_BUFF_OFF,AX
  326.                 MOV     AX,OFFSET NBPOST
  327.                 MOV     CB.NCB_POST_OFF,AX
  328.                                                 ;Function Code
  329.                 MOV     AL,RECEIVEDATAGRAM+NCB_NOWAIT
  330.                 MOV     CB.NCB_COMMAND,AL
  331.                 MOV     BX,OFFSET CB            ;ES:BX -> NCB
  332.                 RET
  333. BUILDRECEIVE    ENDP
  334.  
  335.  
  336. ;╒═══════════════════════════════════════════════════════════════════════════╕
  337. ;│ VALIDATE Function --- Validate the D/T buff contents.                     │
  338. ;╘═══════════════════════════════════════════════════════════════════════════╛
  339.  
  340. VALIDATE        PROC    NEAR
  341.                 CMP     DATETIME+00h,'D'        ;Validate received data
  342.                 JNE     FUNKY
  343.                 CMP     DATETIME+01h,'/'
  344.                 JNE     FUNKY
  345.                 CMP     DATETIME+02h,'T'
  346.                 JNE     FUNKY
  347.                 CMP     DATETIME+03h,00h
  348.                 JNE     FUNKY
  349.                 CMP     DATETIME+0Ch,00h
  350.                 JNE     FUNKY
  351.                 CMP     DATETIME+0Fh,00h
  352.                 JNE     FUNKY
  353.                 MOV     AH,DATETIME+04h         ;Form checksum
  354.                 MOV     AL,DATETIME+05h
  355.                 MOV     BH,DATETIME+06h
  356.                 MOV     BL,DATETIME+07h
  357.                 ADD     AX,BX
  358.                 MOV     BH,DATETIME+08h
  359.                 MOV     BL,DATETIME+09h
  360.                 ADD     AX,BX
  361.                 MOV     BH,DATETIME+0Ah
  362.                 MOV     BL,DATETIME+0Bh
  363.                 ADD     AX,BX
  364.                 CMP     AX,WORD PTR DATETIME+0Dh
  365.                 JNE     FUNKY
  366.                 CLC                             ;Happy stuff, clear carry
  367.                 RET
  368. FUNKY:
  369.                 STC                             ;Invalide stuff, set carry
  370.                 RET
  371. VALIDATE        ENDP
  372.  
  373.  
  374. ;╒═══════════════════════════════════════════════════════════════════════════╕
  375. ;│ CONVERTTIME Function --- Take TIME from D/T buff, Convert for DOS call.   │
  376. ;╘═══════════════════════════════════════════════════════════════════════════╛
  377.  
  378. CONVERTTIME     PROC    NEAR
  379.                 MOV     AL,DATETIME+08h         ;Hour
  380.                 SHR     AL,4
  381.                 MUL     TEN
  382.                 MOV     AH,DATETIME+08h
  383.                 AND     AH,0Fh
  384.                 ADD     AL,AH
  385.                 MOV     CH,AL
  386.                 MOV     AL,DATETIME+09h         ;Minutes
  387.                 SHR     AL,4
  388.                 MUL     TEN
  389.                 MOV     AH,DATETIME+09h
  390.                 AND     AH,0Fh
  391.                 ADD     AL,AH
  392.                 MOV     CL,AL
  393.                 MOV     AL,DATETIME+0Ah         ;Seconds
  394.                 SHR     AL,4
  395.                 MUL     TEN
  396.                 MOV     AH,DATETIME+0Ah
  397.                 AND     AH,0Fh
  398.                 ADD     AL,AH
  399.                 MOV     DH,AL
  400.                 MOV     DL,ZERO
  401.                 RET
  402. CONVERTTIME     ENDP
  403.  
  404.  
  405. ;╒═══════════════════════════════════════════════════════════════════════════╕
  406. ;│ CONVERTDATE Function --- Take DATE from D/T buff, Convert for DOS call.   │
  407. ;╘═══════════════════════════════════════════════════════════════════════════╛
  408.  
  409. CONVERTDATE     PROC    NEAR
  410.                 MOV     AL,DATETIME+04h         ;Century
  411.                 SHR     AL,4
  412.                 MUL     TEN
  413.                 MOV     AH,DATETIME+04h
  414.                 AND     AH,0Fh
  415.                 ADD     AL,AH
  416.                 XOR     AH,AH
  417.                 MUL     HUNDRED
  418.                 MOV     CX,AX
  419.                 MOV     AL,DATETIME+05h         ;Year
  420.                 SHR     AL,4
  421.                 MUL     TEN
  422.                 MOV     AH,DATETIME+05h
  423.                 AND     AH,0Fh
  424.                 ADD     AL,AH
  425.                 XOR     AH,AH
  426.                 ADD     CX,AX
  427.                 MOV     AL,DATETIME+06h         ;Month
  428.                 SHR     AL,4
  429.                 MUL     TEN
  430.                 MOV     AH,DATETIME+06h
  431.                 AND     AH,0Fh
  432.                 ADD     AL,AH
  433.                 MOV     DH,AL
  434.                 MOV     AL,DATETIME+07h         ;Day
  435.                 SHR     AL,4
  436.                 MUL     TEN
  437.                 MOV     AH,DATETIME+07h
  438.                 AND     AH,0Fh
  439.                 ADD     AL,AH
  440.                 MOV     DL,AL
  441.                 RET
  442. CONVERTDATE     ENDP
  443.  
  444.  
  445. ;╔═══════════════════════════════════════════════════════════════════════════╗
  446. ;║ CALL NETBIOS - This routine is called to send an NCB to the NETBIOS.      ║
  447. ;║     If a redirector is loaded use int 2Ah otherwise use int 5Ch.          ║
  448. ;║                                                                           ║
  449. ;║ On entry:                                                                 ║
  450. ;║     ES:BX    addr of NCB                                                  ║
  451. ;║ On exit:                                                                  ║
  452. ;║     AX       return code                                                  ║
  453. ;╚═══════════════════════════════════════════════════════════════════════════╝
  454.  
  455. CALLNB          PROC    NEAR
  456.                 CMP     REDIRACTIVE,0           ;Is a redirector active?
  457.                 JNE     THRUREDIR
  458.                 INT     5Ch
  459.                 RET
  460. THRUREDIR:
  461.                 MOV     AX,0400h
  462.                 INT     2Ah
  463.                 RET
  464. CALLNB          ENDP
  465.  
  466.  
  467. ;╞═══════════════════════════════════════════════════════════════════════════╡
  468. PC              =       $                       ;End of Code, OFFSET -> PC
  469.  
  470. STACKBOT        =       PC                      ;Stacks starts after code      
  471. PC              =       PC + STACKSIZE          ; and is STACKSIZE bytes long
  472. STACKTOP        =       PC                      ;STACKTOP1 here since stack
  473.                                                 ; grows downward
  474.  
  475. LASTBYTE        =       PC                      ;LASTBYTE in resident code
  476.  
  477.  
  478. ;╔═══════════════════════════════════════════════════════════════════════════╗
  479. ;║ Initialization Procedure                                                  ║
  480. ;╚═══════════════════════════════════════════════════════════════════════════╝
  481.  
  482. INITIALIZE      PROC    NEAR
  483.         ASSUME  CS:CSEG,DS:CSEG,ES:CSEG,SS:CSEG ;Set by loader.
  484.  NOP ;          INT     3                       ;Debug or NOP
  485.                 MOV     AX,CS
  486.                 MOV     DS,AX
  487.                 MOV     AH,9
  488.                 MOV     DX,OFFSET COPYRIGHT
  489.                 INT     21H
  490. ;╒═══════════════════════════════════════════════════════════════════════════╕
  491. ;│ Pick up parameters from the command line (options or group name suffix)   │
  492. ;╘═══════════════════════════════════════════════════════════════════════════╛
  493. GETPARMS:                                       ;Command line parms reside in
  494.                 PUSH    0080h                   ; the PSP @ offset 0x80
  495.                 CALL    GETOPT                  ;Process parms
  496.                 OR      AH,AH
  497.                 JZ      SUCCESS
  498.                 PUSH    OFFSET CS:ABANDON       ;Abend
  499.                 CALL    FAILPROG
  500. SUCCESS:
  501.                 OR      AL,AL                   ;Check result
  502.                 JZ      GOTNAME                 ;ZERO, means no suffix char
  503.                 MOV     BX,OFFSET MYNAME        ;BX->MYNAME
  504.                 MOV     CX,16                   ;CX= length of MYNAME (16)
  505.                 JMP     SPACELOOP               ;Begin look for first blank
  506. NEXTINNAME:
  507.                 DEC     CX                      ;Decrement count
  508.                 JZ      NOBLANKS                ;If it goes to 0, no find!
  509.                 INC     BX                      ;Bump pointer into MYNAME
  510. SPACELOOP:
  511.                 CMP     BYTE PTR [BX],' '       ;Is the char blank?
  512.                 JNE     NEXTINNAME              ;NO, loop back to next char
  513.                 JMP     BLANKFOUND              ;YES, alright!  Go plug suffix
  514. NOBLANKS:
  515.                 PUSH    OFFSET CS:NAMETOOLONG   ;MYNAME contains no blanks!
  516.                 CALL    FAILPROG                ;Die
  517. BLANKFOUND:
  518.                 MOV     BYTE PTR [BX],AL        ;Put suffix on group name
  519. ;╒═══════════════════════════════════════════════════════════════════════════╕
  520. ;│ Check to see that NETBIOS is active.  Check for a redirector.             │
  521. ;╘═══════════════════════════════════════════════════════════════════════════╛
  522. GOTNAME:
  523.                 CALL    CHECKDOS                ;DOS better be 3.1 or greater
  524.                 CALL    CHKNETB                 ;See if NETBIOS is in here
  525.                 JNC     NBTHERE
  526.                 PUSH    OFFSET CS:NASTYGRAM     ;Whoa!  No NETBIOS!
  527.                 CALL    FAILPROG                ;Die.
  528. NBTHERE:     
  529.                 MOV     AH,0
  530.                 INT     2Ah                     ;Check for redirector
  531.                 MOV     REDIRACTIVE,AH
  532. ;╒═══════════════════════════════════════════════════════════════════════════╕
  533. ;│ Add our name to the NETBIOS name table.                                   │
  534. ;╘═══════════════════════════════════════════════════════════════════════════╛
  535.                 CALL    CLEARNCB                ;Zero the NCB first
  536.                 MOV     AL,ADDGROUPNAME         ;Fill in NCB fields
  537.                 MOV     CB.NCB_COMMAND,AL
  538.                 MOV     DI,OFFSET CB.NCB_NAME
  539.                 MOV     SI,OFFSET MYNAME
  540.                 MOV     CX,16   
  541.                 CLD
  542.                 REP     MOVSB
  543.                 MOV     BX,OFFSET CB
  544.                 CALL    CALLNB                  ;Call NETBIOS
  545.                 MOV     AL,CB.NCB_RETCODE
  546.                 OR      AL,AL                   ;Check status
  547.                 JZ      ADDWASOK
  548.                 PUSH    OFFSET CS:ADDFAILED     ;Whoa!  It didn't work.
  549.                 CALL    FAILPROG                ;Die.
  550. ADDWASOK:
  551.                 MOV     AL,CB.NCB_NUM           ;Grab "name number" returned
  552.                 MOV     NAMENUM,AL              ; and save it for use later.
  553. ;╒═══════════════════════════════════════════════════════════════════════════╕
  554. ;│ Get the current address of Int 1C and save (it's the timer interrupt)     │
  555. ;╘═══════════════════════════════════════════════════════════════════════════╛
  556.                 MOV     AH,35h                  ;Get Int vector
  557.                 MOV     AL,1Ch                  ;For this Int
  558.                 INT     21h                     ;Result in ES:BX
  559.         ASSUME  ES:NOTHING
  560.                 MOV     WORD PTR PREV1Ch[0],BX  ;offset
  561.                 MOV     WORD PTR PREV1Ch[2],ES  ;segment
  562. ;╒═══════════════════════════════════════════════════════════════════════════╕
  563. ;│ Get the current address of Int 28 and save (it's the idle interrupt)      │
  564. ;╘═══════════════════════════════════════════════════════════════════════════╛
  565.                 MOV     AH,35h                  ;Get Int vector
  566.                 MOV     AL,28h                  ;For this Int
  567.                 INT     21h                     ;Result in ES:BX
  568.                 MOV     WORD PTR PREV28h[0],BX  ;offset
  569.                 MOV     WORD PTR PREV28h[2],ES  ;segment
  570. ;╒═══════════════════════════════════════════════════════════════════════════╕
  571. ;│ Free our environment segment to save a little space.                      │
  572. ;╘═══════════════════════════════════════════════════════════════════════════╛
  573.                 PUSH    DS
  574.                 MOV     AH,62h                  ;Get PSP address
  575.                 INT     21h                     ;
  576.                 MOV     DS,BX
  577.                 MOV     ES,DS:2Ch               ;ES<-Env Seg Addr
  578.                 MOV     AH,49h                  ;Free memory alloc
  579.                 INT     21h                     ;
  580.                 POP     DS
  581. ;╒═══════════════════════════════════════════════════════════════════════════╕
  582. ;│ Get the address of the INDOS flag.                                        │
  583. ;╘═══════════════════════════════════════════════════════════════════════════╛
  584.                 MOV     AH,34h                  ;Get InDos function
  585.                 INT     21h                     ; from DOS
  586.                 MOV     WORD PTR INDOS[0],BX
  587.                 MOV     WORD PTR INDOS[2],ES
  588.                 PUSH    DS
  589.                 MOV     AX,5D06h                ;Get Critical Error function
  590.                 INT     21h
  591.                 MOV     WORD PTR CS:CRIT[0],SI
  592.                 MOV     WORD PTR CS:CRIT[2],DS
  593.                 POP     DS
  594. ;╒═══════════════════════════════════════════════════════════════════════════╕
  595. ;│ Hang a RECEIVE DATAGRAM on the line.                                      │
  596. ;╘═══════════════════════════════════════════════════════════════════════════╛
  597. TRYTORECEIVE:
  598.                 CALL    CLEARNCB                ;Zero the NCB first
  599.                 CALL    BUILDRECEIVE
  600.                 MOV     AL,RECEIVEDATAGRAM+NCB_NOWAIT
  601.                 MOV     CB.NCB_COMMAND,AL
  602.                 MOV     HAVEBUFF,AL
  603.                 CALL    CALLNB                  ;Call NETBIOS
  604. POLLNET:
  605.                 MOV     AL,CB.NCB_CMD_CPLT      ;Poll for completion
  606.                 CMP     AL,0FFh                 ;Still "in progress"?
  607.                 JNE     GOTMSG                  ;NO, it finished
  608.                 MOV     AH,01h                  ;YES, Test keyboard
  609.                 INT     16h                     ;Via the BIOS
  610.                 JZ      POLLNET                 ;Nothing pending, loop back
  611.                 MOV     DI,OFFSET FUNKYNCB      ;Keystroke detected...
  612.                 MOV     CX,NCB_SIZE             ;Zero the alternate NCB
  613.                 XOR     AL,AL
  614.                 CLD
  615.                 REP     STOSB
  616.                 MOV     BX,OFFSET FUNKYNCB
  617.                 MOV     AL,CANCELCMD            ;Cancel the outstanding
  618.                 MOV     FUNKYNCB.NCB_COMMAND,AL ; RECEIVEDATAGRAM command
  619.                 MOV     FUNKYNCB.NCB_BUFF_OFF,OFFSET CB
  620.                 MOV     FUNKYNCB.NCB_BUFF_SEG,DS
  621.                 MOV     AH,09h
  622.                 MOV     DX,OFFSET CANCELLING
  623.                 INT     21h
  624.                 CALL    CALLNB
  625.                 PUSH    OFFSET CS:KEYSTROKE
  626.                 CALL    FAILPROG                
  627. GOTMSG:
  628.                 MOV     AL,CB.NCB_RETCODE
  629.                 OR      AL,AL                   ;Check status
  630.                 JZ      REQWASOK
  631.                 PUSH    OFFSET CS:REQFAILED     ;Whoa!  It didn't work.
  632.                 CALL    FAILPROG                ;Die.
  633. REQWASOK:
  634.                 PUSH    CS
  635.                 POP     ES
  636.                 MOV     CX,16                   ;Save data received
  637.                 MOV     DI,OFFSET DATETIME
  638.                 MOV     SI,OFFSET BUFF
  639.                 CLD
  640.                 REP     MOVSB
  641.                 CALL    VALIDATE                ;Validate received data
  642.                 JC      TRYTORECEIVE
  643. ;
  644.                 MOV     CH,DATETIME+04h         ;Set date in CMOS
  645.                 MOV     CL,DATETIME+05h
  646.                 MOV     DH,DATETIME+06h
  647.                 MOV     DL,DATETIME+07h
  648.                 MOV     AH,05h
  649.                 INT     1Ah
  650.                 CALL    CONVERTDATE             ;Set date in DOS
  651.                 MOV     AH,2Bh
  652.                 INT     21h
  653.                 MOV     CH,DATETIME+08h         ;Set time in CMOS
  654.                 MOV     CL,DATETIME+09h
  655.                 MOV     DH,DATETIME+0Ah
  656.                 MOV     DL,DATETIME+0Bh
  657.                 MOV     AH,03h
  658.                 INT     1Ah
  659.                 CALL    CONVERTTIME             ;Set time in DOS
  660.                 MOV     AH,2Dh
  661.                 INT     21h
  662.                 XOR     AX,AX
  663.                 MOV     COUNTER,AX              ;Zero counter
  664.                 MOV     LASTSTATUS,0FFh
  665. ;╒═══════════════════════════════════════════════════════════════════════════╕
  666. ;│ Plug ourselves into DOS Idle Interrupt (Interrupt 28).                    │
  667. ;╘═══════════════════════════════════════════════════════════════════════════╛
  668.                 PUSH    DS
  669.                 PUSH    CS
  670.                 POP     DS
  671.                 MOV     DX,OFFSET INT_28        ;INT_28 is ISR entry
  672.                 MOV     AH,25h                  ;Set Interrupt vector
  673.                 MOV     AL,28h                  ; 28h.
  674.                 INT     21h                     ; 
  675.                 POP     DS
  676. ;╒═══════════════════════════════════════════════════════════════════════════╕
  677. ;│ Plug ourselves into DOS Timer Interrupt (Interrupt 1C).                   │
  678. ;╘═══════════════════════════════════════════════════════════════════════════╛
  679.                 PUSH    DS
  680.                 PUSH    CS
  681.                 POP     DS
  682.                 MOV     DX,OFFSET INT_1C        ;INT_1C is ISR entry
  683.                 MOV     AH,25h                  ;Set Interrupt vector
  684.                 MOV     AL,1Ch                  ; 1Ch.
  685.                 INT     21h                     ; 
  686.                 POP     DS
  687. ;╒═══════════════════════════════════════════════════════════════════════════╕
  688. ;│ Terminate and stay resident.                                              │
  689. ;╘═══════════════════════════════════════════════════════════════════════════╛
  690.                 MOV     AX,3100H
  691.                 MOV     DX,(OFFSET LASTBYTE - OFFSET CSEG + 15) SHR 4
  692.                 INT     21H
  693.  
  694. INITIALIZE      ENDP
  695.  
  696. ABANDON         DB      "TIMERECV did NOT remain resident",0Ah,0Dh,'$'
  697. NASTYGRAM       DB      "NETBIOS is NOT active on this system",0Ah,0Dh,'$'
  698. ADDFAILED       DB      "NETBIOS Add Name failed",0Ah,0Dh,'$'
  699. REQFAILED       DB      "NETBIOS Recieve Datagram failed",0Ah,0Dh,'$'
  700. NAMETOOLONG     DB      "NETBIOS Name too long to add suffix",0Ah,0Dh,'$'
  701. CANCELLING      DB      "Cancelling Receive Datagram request",0Ah,0Dh,'$'
  702. KEYSTROKE       DB      "Initialization terminated by keystroke",0Ah,0Dh,'$'
  703.  
  704.  
  705. ;╒═══════════════════════════════════════════════════════════════════════════╕
  706. ;│ FAILPROG  ---  Display string (terminated with "$") on console, then      │
  707. ;│                exit the program with nonzero condition code.              │
  708. ;╘═══════════════════════════════════════════════════════════════════════════╛
  709.  
  710. FAILPROG        PROC    NEAR
  711.                 PUSH    SP
  712.                 POP     BX
  713.                 MOV     DX,WORD PTR [BX+2]      ;Get offset of string
  714.                 PUSH    CS                      ;Assume offset w/in this code
  715.                 POP     DS
  716.                 MOV     AH,09h                  ;Display String function
  717.                 INT     21h                     ; of DOS
  718.                 MOV     AH,4Ch                  ;Terminate a Process func
  719.                 MOV     AL,01h                  ; of DOS
  720.                 INT     21h                     ;
  721.                 INT     20h                     ;Just to be safe....
  722. FAILPROG        ENDP
  723.  
  724.  
  725. ;╒═══════════════════════════════════════════════════════════════════════════╕
  726. ;│ CHECKDOS  ---  Get the DOS version. Bomb if < DOS 3.10.                   │
  727. ;╘═══════════════════════════════════════════════════════════════════════════╛
  728.  
  729. CHECKDOS        PROC    NEAR
  730.                 PUSH    BP                      ;Save register(s)
  731.                 MOV     BP,SP
  732.                 PUSH    CX                      
  733.                 PUSH    BX                      
  734.                 PUSH    AX
  735.                 MOV     AH,30h                  ;Get DOS Version
  736.                 INT     21h
  737.                 MOV     CS:VER,AX               ;Save results
  738.                 MOV     CS:DOSMAJOR,AL
  739.                 MOV     CS:DOSMINOR,AH
  740.                 CMP     AL,3                    ;Check major level
  741.                 JL      VERCHOKE                ;<3, VERCHOKE
  742.                 JNE     VEROK                   ;>3, VEROK     
  743.                 CMP     AH,1                    ;Check minor level for 3.x
  744.                 JGE     VEROK                   ;VEROK if 3.1 or better
  745. VERCHOKE:
  746.                 PUSH    OFFSET CS:VERMSG        ;Push offset of nastygram
  747.                 CALL    FAILPROG                ;And kiss off....
  748. VEROK:
  749.                 POP     AX                      ;Restore registers
  750.                 POP     BX
  751.                 POP     CX
  752.                 MOV     SP,BP                   ;Restore stack
  753.                 POP     BP
  754.                 RET                             ;Return to caller
  755. CHECKDOS        ENDP                
  756.  
  757. VERMSG          DB      "DOS Version MUST be 3.1 or greater$"
  758.  
  759.  
  760. ;╔═══════════════════════════════════════════════════════════════════════════╗
  761. ;║ Check For NETBIOS Installed in System                                     ║
  762. ;║ Return with CARRY SET if NOT installed                                    ║
  763. ;╚═══════════════════════════════════════════════════════════════════════════╝
  764.  
  765. CHKNETB         PROC    NEAR
  766.                 MOV     AH,35h                  ;Who's plugged into INT 5C?
  767.                 MOV     AL,5Ch
  768.                 INT     21h
  769.                 MOV     AX,ES
  770.                 CMP     AX,0000h
  771.                 JE      NOTKOSHER
  772.                 CMP     AX,0F000h
  773.                 JE      NOTKOSHER
  774. ITSPLUGGED:
  775.                 PUSH    CS
  776.                 POP     ES
  777.                 MOV     DI,OFFSET FUNKYNCB      ;Zero the NCB
  778.                 MOV     CX,NCB_SIZE
  779.                 XOR     AL,AL
  780.                 CLD
  781.                 REP     STOSB
  782.                 MOV     BX,OFFSET FUNKYNCB
  783.                 MOV     AL,0FFh
  784.                 MOV     FUNKYNCB.NCB_COMMAND,AL
  785.                 MOV     AL,00h
  786.                 INT     5Ch                     ;Check it.
  787.                 MOV     AL,FUNKYNCB.NCB_RETCODE
  788.                 CMP     AL,03h                  ;Zero ?
  789.                 JNE     NOTKOSHER               ;Yes, so not installed.
  790.                 CLC
  791.                 RET
  792. NOTKOSHER:  
  793.                 STC
  794.                 RET
  795.  
  796. FUNKYNCB        NCB     <>                      ;NCB with FUNKY command
  797.                                                 ; to test things out
  798. CHKNETB         ENDP
  799.  
  800.  
  801. ;╒═══════════════════════════════════════════════════════════════════════════╕
  802. ;│ GETOPT Function --- Get options or NETBIOS group name to use              │
  803. ;╘═══════════════════════════════════════════════════════════════════════════╛
  804.  
  805. GETOPT          PROC    NEAR
  806.                 ENTER   WORD PTR 0,0
  807. ; Stack frame   STRING  offset +4
  808.                 MOV     AL,BYTE PTR [BP+4]      ;STRING
  809.                 MOV     BL,AL                   ;BX points to parm line
  810.                 XOR     BH,BH
  811.                 MOV     AL,BYTE PTR [BX]        ;CX contains line length
  812.                 MOV     CL,AL
  813.                 XOR     CH,CH
  814.                 INC     BX                      ;BX += 1
  815.                 JMP     SHORT PASSONE           ;Find 1st nonblank char
  816. BLANKLOOP:
  817.                 MOV     AX,CX                   ;N
  818.                 DEC     CX                      ;N
  819.                 OR      AX,AX
  820.                 JE      ENDLOOP
  821.                 INC     BX                      ;P
  822. PASSONE:
  823.                 CMP     BYTE PTR [BX],' '
  824.                 JE      BLANKLOOP
  825. ENDLOOP:
  826.                 CMP     CX,0                    ;N
  827.                 JNE     FIND
  828.                 XOR     AX,AX                   ;Return a ZERO which
  829.                 LEAVE                           ; indicates "no suffix"
  830.                 RET     
  831. FIND:
  832.                 MOV     AL,BYTE PTR [BX]
  833.                 CMP     AL,'/'
  834.                 JE      ITSASLASH
  835.                 CMP     AL,'?'
  836.                 JNE     SUFFIX
  837.                 CALL    SHOWHELP
  838.                 JMP     OPTEXIT
  839. ;               Seems to be the NETBIOS name suffix to use
  840. SUFFIX:
  841.                 PUSH    AX
  842.                 CALL    TOUPPER
  843.                 ADD     SP,2
  844.                 MOV     BYTE PTR [BX],AL
  845.                 CMP     AL,'0'                  ;Validate the suffix
  846.                 JL      BADCHAR                 ; character. 0-9 or A-Z.
  847.                 CMP     AL,'9'
  848.                 JLE     CHAROK
  849.                 CMP     AL,'A'
  850.                 JL      BADCHAR
  851.                 CMP     AL,'Z'
  852.                 JLE     CHAROK 
  853. BADCHAR: 
  854.                 PUSH    OFFSET CS:INVALIDMSG    ;Say "Bad Suffix Char..."
  855.                 CALL    FAILPROG
  856. CHAROK: 
  857.                 XOR     AH,AH
  858.                 MOV     AL,BYTE PTR [BX]
  859.                 LEAVE   
  860.                 RET     
  861. ITSASLASH:
  862.                 INC     BX                      ;Look at option char
  863.                 MOV     AL,BYTE PTR [BX]        ;Make it upper case
  864.                 CMP     AL,'?'
  865.                 JNE     NOTHELP
  866.                 CALL    SHOWHELP
  867.                 JMP     OPTEXIT
  868. NOTHELP:
  869.                 PUSH    AX
  870.                 CALL    TOUPPER
  871.                 ADD     SP,2
  872.                 CMP     AL,'U'                  ;/U ?
  873.                 JE      DOUNLOAD                ;YES, go do unload
  874.                 CALL    SHOWHELP                ;NO, show help 
  875.                 JMP     OPTEXIT                 ; and then exit.
  876. DOUNLOAD:
  877.                 CALL    UNLOAD                  ;Invoke unload logic
  878. OPTEXIT:
  879.                 MOV     AH,01h
  880.                 XOR     AL,AL                   ;Return a ZERO which
  881.                 LEAVE                           ; indicates "no suffix"
  882.                 RET     
  883.                 NOP     
  884. GETOPT          ENDP
  885.  
  886. INVALIDMSG      DB      "Invalid name suffix character.",0Ah,0Dh,'$'
  887.  
  888. ;╔═══════════════════════════════════════════════════════════════════════════╗
  889. ;║ Show the Help Text                                                        ║
  890. ;╚═══════════════════════════════════════════════════════════════════════════╝
  891.  
  892. SHOWHELP        PROC    NEAR
  893.                 MOV     DX,OFFSET CS:HELPLINE   ;Get offset of help string
  894.                 MOV     AH,09h                  ;Display String function
  895.                 INT     21h                     ; of DOS
  896.                 RET
  897. SHOWHELP        ENDP
  898.  
  899. HELPLINE        DB      "     To LOAD->  TIMERECV <x>  where x=name suffix"
  900.                 DB       0Ah,0Dh
  901.                 DB      "Or To UNLOAD->  TIMERECV /U"
  902.                 DB       0Ah,0Dh,'$' 
  903.  
  904. ;╔═══════════════════════════════════════════════════════════════════════════╗
  905. ;║ Request TIMERECV Unload From Memory                                       ║
  906. ;╚═══════════════════════════════════════════════════════════════════════════╝
  907.  
  908. UNLOAD          PROC    NEAR
  909.                 PUSH    CS:OFFSET CS:NOTYET     ;Get offset of "Not yet..."
  910.                 CALL    FAILPROG                ;Die.
  911. UNLOAD          ENDP
  912.  
  913. NOTYET:         DB      "Unload of TIMERECV not yet supported",0Ah,0Dh,'$'
  914.  
  915. ;╔═══════════════════════════════════════════════════════════════════════════╗
  916. ;║ Convert Character in AL to Upper Case ASCII                               ║
  917. ;╚═══════════════════════════════════════════════════════════════════════════╝
  918.  
  919. TOUPPER         PROC    NEAR
  920.                 CMP     AL,'a'                  ;LESS THAN 'a'?
  921.                 JL      ITSOK                   ;YES, DOESN'T NEED CONVERTING
  922.                 CMP     AL,'z'                  ;NO, GREATER THAN 'z'?
  923.                 JG      ITSOK                   ;YES, DOESN'T NEED CONVERTING
  924.                 SUB     AL,32                   ;NO, IT'S BETWEEN 'a' & 'z'
  925. ITSOK:          RET                             ;Return to caller
  926. TOUPPER         ENDP
  927.  
  928. CSEG    ENDS
  929.  
  930.         END     ENTPT
  931.  
  932. ;╔═══════════════════════════════════════════════════════════════════════════╗
  933. ;║ End of Program --- TIMERECV                                               ║
  934. ;╚═══════════════════════════════════════════════════════════════════════════╝
  935. 
  936.